Skip to content

Drop Python 3.9 support - #1597

Open
MankhongGarden wants to merge 2 commits into
PyThaiNLP:devfrom
MankhongGarden:fix/drop-python-3.9
Open

MankhongGarden wants to merge 2 commits into
PyThaiNLP:devfrom
MankhongGarden:fix/drop-python-3.9

Conversation

@MankhongGarden

Copy link
Copy Markdown

What do these changes do

Drops Python 3.9 support, as agreed in #1592. Python 3.10 is now the earliest supported version. Also runs Bandit on Python 3.14.

What was wrong

  • The ubuntu-latest (26.04) runner no longer provides Python 3.9, so the 3.9 unit test jobs and the mypy job fail on dev and on every PR.
  • Bandit used python-version: "3.x", which now resolves to 3.15. There, pip cannot install bandit's PyYAML dependency.

How this fixes it

Commit 1, drop Python 3.9:

  • pyproject.toml: requires-python = ">=3.10", remove the 3.9 classifier, Ruff target-version = "py310", mypy python_version = "3.10", remove py39 from tox, and remove the dev dependency pins that only applied to Python 3.9.
  • unittest.yml: 3.10 replaces 3.9 as the earliest version on all three OSes. The ubuntu-only 3.10 entry is removed, so the matrix still has 9 jobs. PyICU 2.15 stays, because it is also the last Windows wheel for cp310 (2.15.2 and later start at cp311).
  • mypy.yml: Python 3.10.
  • With the py310 target, Ruff UP035 flags typing.Callable, so Callable now comes from collections.abc. Where get_type_hints() needs it at runtime (util/time.py, augment/wordnet.py), the import stays at module level with # noqa: TC003, as in util/strftime.py.
  • README badges, the dev row of the version table, tests/README.md, and CHANGELOG.md ("The minimum Python version is now 3.10.", as for 3.9 in 5.3.0).
  • Removes the 3.9 reason from a comment in pypi-publish.yml. Pitloom's Hatchling build hook may now be usable instead of embedding the SBOM after the build. This PR does not change that; it is your call for a separate change.

Commit 2 pins Bandit to Python 3.14, as the lint, corpus, and docs workflows already do.

Testing (Windows 11):

  • ruff check, ruff format --check, flake8 pythainlp, and mypy pythainlp tests (1.19.1, target 3.10) pass.
  • python -m unittest tests.core on Python 3.10.22: 752 tests, 71 skipped, 1 error. The error is test_is_within_directory_with_symlinks, because os.symlink needs extra privileges on Windows. It is unrelated to this change.
  • typing.get_type_hints(pythainlp.util.time) returns the same 7 hints as on dev.

Fixes #1592

Your checklist for this pull request

  • Passed code styles and structures
  • Passed code linting checks and unit test

Python 3.9 reached end of life in October 2025, and the ubuntu-latest
(26.04) runner no longer provides it, so the 3.9 jobs fail.

- Set requires-python to >=3.10 and remove the 3.9 classifier
- Make Python 3.10 the earliest version in the test matrix and mypy job
- Set the Ruff target to py310 and the mypy target to 3.10
- Remove dev dependency pins that only applied to Python 3.9
- Import Callable from collections.abc (Ruff UP035 with the new target)
- Update the README badges, the test matrix table, and the changelog
"3.x" now resolves to Python 3.15, where pip cannot install bandit's
PyYAML dependency. Use 3.14, as the other workflows do.
@sonarqubecloud

sonarqubecloud Bot commented Nov 7, 2026

Copy link
Copy Markdown

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 73.111% (+0.008%) from 73.103% — MankhongGarden:fix/drop-python-3.9 into PyThaiNLP:dev

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants